// 抛出错误  
// 创建一个错误  new Error('错误信息')
// throw new Error('错误信息')

// 将对象转成 查询字符串 
// {
//     name:'张三',
//     age:18,
//     height:'181cm'
// }
// name=张三&age=18&height=181cm
// 等同于下面三个拼接起来
// name=张三&
// age=18&
// height=181cm&
// 再去掉最后一个字符 & 
function querystringify(obj){
    let s = '';
    for(let k in obj){
        s+=`${k}=${obj[k]}&`
    }
    return s.slice(0,-1);
}


function myajax(options={}){
    //1. 参数验证 
    // 请求地址是否有
    if(!options.url){
        throw new Error('url是必须填的')
    }

    // if(!options.method){
    //     options.method = 'GET'
    // }

    // if(!(/^(GET|POST|DELETE|PUT|PATCH)$/i.test(options.method))){
    //     throw new Error('method是必须是GET或者POST或者DELETE')
    // }

    if(!(options.method === undefined || /^(GET|POST|DELETE|PUT|PATCH)$/i.test(options.method))){
        // 表示method 传递了内容 但是内容不是 GET POST DELETE PUT PATCH 
        throw new Error('method是必须是GET或者POST或者DELETE');
    }


    if(!(options.async === undefined || typeof options.async === 'boolean')){
        // 表示method 传递了是否是异步 但是内容不是布尔类型 
        throw new Error('async是必须是布尔类型');
    }

    if(!(options.data === undefined || typeof options.data === 'string' || options.data.constructor === Object)){
        // 表示method 传递了携带的参数 但是内容不是字符串 或者对象   
        throw new Error('携带的参数,必须是字符串或者对象');
    }


    if(!(options['content-type'] === undefined || options['content-type'] === 'application/x-www-form-urlencoded' || options['content-type'] === 'application/json' || options['content-type'] === 'multipart/form-data')){
        // 表示method 传递了content-type 但是内容不是 查詢字符串  json 二進制流   
        throw new Error('data參數必須是二進制流 json 或者 查詢字符串');   
    }


    // 当走到这里 说明 参数都是对的  
    // 准备默认值  
    const _default = {
        url:options.url,
        method:(options.method || 'GET').toUpperCase(),
        async: typeof options.async === 'boolean'? options.async:true,
        data:options.data || '',
        'content-type':options['content-type'] || 'application/x-www-form-urlencoded',
        dataType:options.dataType || 'string'
    }

    // console.log(_default);

    // get 请求  携带参数  是在请求地址后边 添加查询字符串 
    // 我们对与参数的要求是  可以传字符串 或者 对象 
    if(_default.method==='GET' && _default.data.constructor === Object){
        _default.data = querystringify(_default.data)
    }
    // post 请求  携带的参数是对象  
    // post 请求需要告知 服务器  数据类型 (查询字符串\json\二进制流字符串)
    if(_default.method==='POST' && _default.data.constructor === Object){
        // 判断  content-type  是application/x-www-form-urlencoded
        if(_default['content-type'] ==='application/x-www-form-urlencoded' ){
            _default.data = querystringify(_default.data)
        }

        if(_default['content-type'] ==='application/json' ){
            _default.data = JSON.stringify(_default.data)
            // console.log(_default.data);
        }
    }


    // get 请求  url地址  请求地址 + '?'+ 查询字符串  
    if(_default.method==='GET'&&  _default.data){
        _default.url += '?'+ _default.data
    }


    // 进行到这里 我们万事俱备了 

    // 用promise  将来 可以  用 .then() 接收成功的结果   

    return new Promise(function(resolve,reject){
        // 创建ajax 对象 
        const xhr = new XMLHttpRequest();

        //配置请求信息  
        xhr.open(_default.method,_default.url,_default.async);


        //注册请求完成事件 
        xhr.onload = function(){
            // 在这里接收服务器返回的结果
            // 如果返回的是json 需要将返回的数据转成js数据类型以后  
            if(_default.dataType === 'json'){
                try{
                    const res = JSON.parse(xhr.responseText);
                    resolve(res);
                }
                catch(error){
                    reject({
                        message:'json数据在解析的过程中出现了错误',
                        info:error,
                    });
                }
            }else{
                resolve(xhr.responseText)
            }
        }


        // 最后一步 发送请求  
        // 如果post请求需要写 setRequestHeader
        // get 请求不需要  

        if(_default.method == 'POST'){
            xhr.setRequestHeader('content-type',_default['content-type'])
            xhr.send(_default.data); 
            // post请求体放到send中  
        }
        else{
            xhr.send();
        }
    });


}


// myajax({
//     url:'',
//     method:'post',
//     async:true,
//     data:{name:'zhangsan',age:18},
//     'content-type':'application/json',
//     dataType:'json'
// }).then(res=>{
//     console.log(res);
// })
// .catch(err=>{
//     console.log(err.message)
// });


